package com.vehiclemanagement.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vehiclemanagement.entity.AccidentRecord;
import com.vehiclemanagement.mapper.AccidentRecordMapper;
import com.vehiclemanagement.service.AccidentRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.Year;
import java.util.List;
import java.util.Map;

/**
 * 车辆事故记录服务实现类
 */
@Service
@Slf4j
public class AccidentRecordServiceImpl extends ServiceImpl<AccidentRecordMapper, AccidentRecord> implements AccidentRecordService {

    @Autowired
    private AccidentRecordMapper accidentRecordMapper;

    @Override
    public IPage<AccidentRecord> pageAccidents(Integer current, Integer size, String searchTerm,
                                            Long vehicleId, Long driverId, Integer accidentType,
                                            Integer responsibility, Integer status,
                                            LocalDateTime startTime, LocalDateTime endTime) {
        Page<AccidentRecord> page = new Page<>(current, size);
        StringBuilder whereSql = new StringBuilder();
        whereSql.append(" ar.del_flag = 0 ");

        if (StringUtils.hasText(searchTerm)) {
            whereSql.append(" AND (v.plate_number LIKE '%").append(searchTerm).append("%'")
                    .append(" OR d.name LIKE '%").append(searchTerm).append("%'")
                    .append(" OR ar.accident_location LIKE '%").append(searchTerm).append("%'")
                    .append(" OR ar.accident_description LIKE '%").append(searchTerm).append("%')");
        }

        if (vehicleId != null) {
            whereSql.append(" AND ar.vehicle_id = ").append(vehicleId);
        }

        if (driverId != null) {
            whereSql.append(" AND ar.driver_id = ").append(driverId);
        }

        if (accidentType != null) {
            whereSql.append(" AND ar.accident_type = ").append(accidentType);
        }

        if (responsibility != null) {
            whereSql.append(" AND ar.responsibility = ").append(responsibility);
        }

        if (status != null) {
            whereSql.append(" AND ar.status = ").append(status);
        }

        if (startTime != null) {
            whereSql.append(" AND ar.accident_time >= '").append(startTime).append("'");
        }

        if (endTime != null) {
            whereSql.append(" AND ar.accident_time <= '").append(endTime).append("'");
        }

        return accidentRecordMapper.selectPageWithInfo(page, whereSql.toString());
    }

    @Override
    public AccidentRecord getAccidentById(Long id) {
        AccidentRecord accident = getById(id);
        if (accident == null) {
            log.error("事故记录不存在, id: {}", id);
            return null;
        }
        return accident;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addAccident(AccidentRecord accident) {
        if (accident == null) {
            log.error("添加事故记录失败: accident不能为空");
            return false;
        }

        // 设置默认值
        accident.setCreateTime(LocalDateTime.now());
        accident.setUpdateTime(LocalDateTime.now());
        accident.setDelFlag(0);
        
        // 默认状态为未处理
        if (accident.getStatus() == null) {
            accident.setStatus(0);
        }
        
        // 计算实际损失
        if (accident.getRepairCost() != null || accident.getCompensationCost() != null || accident.getInsuranceClaimAmount() != null) {
            BigDecimal repairCost = accident.getRepairCost() != null ? accident.getRepairCost() : BigDecimal.ZERO;
            BigDecimal compensationCost = accident.getCompensationCost() != null ? accident.getCompensationCost() : BigDecimal.ZERO;
            BigDecimal insuranceClaimAmount = accident.getInsuranceClaimAmount() != null ? accident.getInsuranceClaimAmount() : BigDecimal.ZERO;
            
            BigDecimal actualLoss = calculateActualLoss(repairCost, compensationCost, insuranceClaimAmount);
            accident.setActualLoss(actualLoss);
        }

        boolean result = save(accident);
        log.info("添加事故记录 {} ", result ? "成功" : "失败");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAccident(AccidentRecord accident) {
        if (accident == null || accident.getId() == null) {
            log.error("更新事故记录失败: accident或ID不能为空");
            return false;
        }

        // 计算实际损失
        if (accident.getRepairCost() != null || accident.getCompensationCost() != null || accident.getInsuranceClaimAmount() != null) {
            BigDecimal repairCost = accident.getRepairCost() != null ? accident.getRepairCost() : BigDecimal.ZERO;
            BigDecimal compensationCost = accident.getCompensationCost() != null ? accident.getCompensationCost() : BigDecimal.ZERO;
            BigDecimal insuranceClaimAmount = accident.getInsuranceClaimAmount() != null ? accident.getInsuranceClaimAmount() : BigDecimal.ZERO;
            
            BigDecimal actualLoss = calculateActualLoss(repairCost, compensationCost, insuranceClaimAmount);
            accident.setActualLoss(actualLoss);
        }

        accident.setUpdateTime(LocalDateTime.now());
        boolean result = updateById(accident);
        log.info("更新事故记录 {} , id: {}", result ? "成功" : "失败", accident.getId());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAccident(Long id) {
        if (id == null) {
            log.error("删除事故记录失败: ID不能为空");
            return false;
        }

        int result = accidentRecordMapper.deletePhysically(id);
        log.info("删除事故记录 {} , id: {}", result > 0 ? "成功" : "失败", id);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handleAccident(Long id, String handler, String handlingResult, String remark) {
        if (id == null) {
            log.error("处理事故记录失败: ID不能为空");
            return false;
        }

        AccidentRecord accident = getById(id);
        if (accident == null) {
            log.error("处理事故记录失败: 记录不存在, id: {}", id);
            return false;
        }

        // 更新处理信息
        accident.setHandler(handler);
        accident.setHandlingResult(handlingResult);
        accident.setHandlingTime(LocalDateTime.now());
        accident.setRemark(remark);
        accident.setStatus(2); // 已处理
        accident.setUpdateTime(LocalDateTime.now());

        boolean result = updateById(accident);
        log.info("处理事故记录 {} , id: {}", result ? "成功" : "失败", id);
        return result;
    }

    @Override
    public BigDecimal calculateActualLoss(BigDecimal repairCost, BigDecimal compensationCost, BigDecimal insuranceClaimAmount) {
        // 确保不为null
        repairCost = repairCost != null ? repairCost : BigDecimal.ZERO;
        compensationCost = compensationCost != null ? compensationCost : BigDecimal.ZERO;
        insuranceClaimAmount = insuranceClaimAmount != null ? insuranceClaimAmount : BigDecimal.ZERO;
        
        // 实际损失 = 维修费 + 赔偿费 - 保险理赔
        return repairCost.add(compensationCost).subtract(insuranceClaimAmount);
    }

    @Override
    public BigDecimal sumRepairCostByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("计算车辆累计维修费用失败: vehicleId不能为空");
            return BigDecimal.ZERO;
        }
        BigDecimal sum = accidentRecordMapper.sumRepairCostByVehicleId(vehicleId);
        return sum == null ? BigDecimal.ZERO : sum;
    }

    @Override
    public BigDecimal sumCompensationCostByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("计算车辆累计赔偿费用失败: vehicleId不能为空");
            return BigDecimal.ZERO;
        }
        BigDecimal sum = accidentRecordMapper.sumCompensationCostByVehicleId(vehicleId);
        return sum == null ? BigDecimal.ZERO : sum;
    }

    @Override
    public BigDecimal sumInsuranceClaimByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("计算车辆累计保险理赔金额失败: vehicleId不能为空");
            return BigDecimal.ZERO;
        }
        BigDecimal sum = accidentRecordMapper.sumInsuranceClaimByVehicleId(vehicleId);
        return sum == null ? BigDecimal.ZERO : sum;
    }

    @Override
    public BigDecimal sumActualLossByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("计算车辆累计实际损失失败: vehicleId不能为空");
            return BigDecimal.ZERO;
        }
        BigDecimal sum = accidentRecordMapper.sumActualLossByVehicleId(vehicleId);
        return sum == null ? BigDecimal.ZERO : sum;
    }

    @Override
    public Integer countAccidentsByDriverId(Long driverId) {
        if (driverId == null) {
            log.error("计算驾驶员累计事故次数失败: driverId不能为空");
            return 0;
        }
        Integer count = accidentRecordMapper.countAccidentsByDriverId(driverId);
        return count == null ? 0 : count;
    }

    @Override
    public List<Map<String, Object>> statisticsByMonth(Integer year) {
        if (year == null) {
            // 默认使用当前年份
            year = LocalDateTime.now().getYear();
        }
        
        LocalDateTime startTime = LocalDateTime.of(year, 1, 1, 0, 0, 0);
        LocalDateTime endTime = LocalDateTime.of(year, 12, 31, 23, 59, 59);
        
        return accidentRecordMapper.statisticsByMonth(startTime, endTime);
    }

    @Override
    public List<Map<String, Object>> statisticsByType() {
        return accidentRecordMapper.statisticsByType();
    }
} 